package org.pearl.springauthorizationserverdemo.config;

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.web.SecurityFilterChain;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by TD on 2021/9/8
 */
@Configuration
public class AuthServerConfig {

    /**
     * 配置客户端
     */
    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        // 授权模式集合
        List<AuthorizationGrantType> grantTypeList=new ArrayList<>();
        grantTypeList.add(AuthorizationGrantType.AUTHORIZATION_CODE);
        grantTypeList.add(AuthorizationGrantType.PASSWORD);
        grantTypeList.add(AuthorizationGrantType.JWT_BEARER);
        grantTypeList.add(AuthorizationGrantType.CLIENT_CREDENTIALS);
        grantTypeList.add(AuthorizationGrantType.REFRESH_TOKEN);
        // 内存中创建客户端
        RegisteredClient client = RegisteredClient.withId("123456")
                .clientId("client")
                .clientSecret(new BCryptPasswordEncoder().encode("secret"))
                .scope("app")
                .authorizationGrantTypes(e ->
                        e.addAll(grantTypeList))
                .redirectUri("https://www.baidu.com")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .build();
        return new InMemoryRegisteredClientRepository(client);
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        return http.formLogin(Customizer.withDefaults()).build();
    }

    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        RSAKey rsaKey = Jwks.generateRsa();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
    }
}
// 授权码 http://localhost:8080/oauth2/authorize?client_id=client&client_secret=secret&response_type=code&redirect_uri=https://www.baidu.com
// http://localhost:8080/oauth2/token